/*
 * Displays results in a new tab
 *
 * Params:
 * aHtmlCode - preprocessed results
 * aPageTitle - page title for the new tab
 */
function openResultPage(aHtmlCode, aPageTitle) {

  // CSS code
  var style = (<r><![CDATA[

    body {
      background-color: #CADCEB;
      font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
    }
    h1 {
      font-size: x-large; color: #105289;
    }
    h2, h3 {
      font-size: large; color: #105289;
    }
    table {
      background-color: #E3E6EE;
      margin-left: auto;
      margin-right: auto;
      width: 100%;
      padding-top: 5px;
      padding-bottom: 5px;
      border: 1px solid #12A3EB;
      border-collapse: collapse;
    }
    a, a:visited {
      color: #105289 !important;
      text-decoration:none !important;
    }
    a:hover {
      color: #D31141 !important;
      text-decoration: underline !important;
    }
    tr {
      background-color: #E1EBF2;
    }
    tr:hover {
      background-color: #CFE1F6;
    }
    td {
      font-size: small; color: #536482;
    }
    th {
      font-size: small;
      color: #FFFFFF;
      background-color: #12A3EB;
    }
    td.date {
      width: 25%;
      padding-left: 5px;
    }
    td.url {
      width: 75%;
      padding-right: 5px;
    }
    td.urllist {
      width: 100%;
      padding-left: 10px;
      padding-right: 10px;
    }
    td.title {
      width: 35%;
      padding-left: 5px;
    }
    td.desc {
      width: 65%;
      padding-right: 5px;
    }
    table.bookmark td, table.bookmark th {
      border-bottom: 1px solid #12A3EB;
    }

    ]]></r>).toString();

  // append CSS before the preprocessed result code
  aHtmlCode = "<style>" + style + "</style>" + aHtmlCode;

  // get browser
  var browser = context.chromeWindow.getBrowser();
  // append new blank tab
  // not using focusUrlInBrowser to prevent interference with existing blank tabs
  // not using openUrlInBrowser because we need a reference to the new tab 
  var newTab = browser.addTab("about:blank");
  // focus on new tab
  browser.selectedTab = newTab;
    
  // This must be done to make generated content render
  // WebDeveloper Toolbar hack
  var request = new XMLHttpRequest();
  request.open("get", "about:blank", false);
  request.send(null);
    
  // getDocument now points to the generated blank tab
  doc = CmdUtils.getDocument();
  doc.body.innerHTML = aHtmlCode;
  doc.title = aPageTitle;
  doc.close();
}

/*
 * Ubiquity command get-all-links
 */
CmdUtils.CreateCommand({
  names: ["get-all-links", "get all links"],
  icon: "http://www.mozilla.org/images/mozilla-16.png",
  homepage: "http://boardraider-ubiquity-commands.googlecode.com/svn/trunk/get-all-links.html",
  author: {name: "boardraider"},
  license: "GPL 2 or newer",
  description: "Gets all tabs in all windows and creates a list of links contained in the documents.",
  arguments: [{
               role: "object",
               nountype: noun_arb_text,
               label: "filter"
             }],
  
  preview: function(pblock, filter) {
    if (filter.object.text.length > 0) {
      var regexp = new RegExp(filter.object.text, "i");
      pblock.innerHTML = _("Gets all tabs in all windows and creates a list of links contained in the documents which match your filter <b>") + regexp + _("</b>.");
    } else {
      pblock.innerHTML = _("Gets all tabs in all windows and creates a list of links contained in the documents.");
    }
  },
  
  execute: function(filter) {
    
    /*
     * Recursive function which gets all content documents from a top level document.
     * Needed for pages which use framesets or iframes.
     *
     * Returns an array containing all found content documents.
     *
     * Params:
     * aDocument - current top level document
     */
    function getDocs(aDocument) {
      // create array to return
      var documents = new Array();
      if (aDocument) { // if we have a valid document
        // add the current top level document to the list
        documents.push(aDocument);
        // get all frames / iframes in the content document,
        // recursive call the function vor each subframe and
        // appending the returned content documents
        var frames = aDocument.getElementsByTagName("frame");
        for  (var i = 0; i < frames.length; i++) {
          documents = documents.concat(getDocs(frames[i].contentDocument));
        }
        frames = aDocument.getElementsByTagName("iframe");
        for  (var i = 0; i < frames.length; i++) {
          documents = documents.concat(getDocs(frames[i].contentDocument));
        }
      }
      // return the list of documents
      return documents;
    }
    
    // get regular expression from parameter
    var regexp = null;
    if (filter.object.text.length > 0) { 
      regexp = new RegExp(filter.object.text, "i");
    }

    var html = _("<h1>List of links:</h1>");
    if (regexp) {
      html += _("<h2>Your regular expression used as filter: ") + regexp + "</h2>";
    }
    
    // create list of links
    html += _("<table><thead><tr><th>URL</th></tr><tbody>");
    // current loop values
    var cTabsList, cDocsList, cLinksList, cHref;
    // iterate over all windows
    for (var i = 0; i < Application.windows.length; i++) {
      cTabsList = Application.windows[i].tabs;
       // iterate over all tabs
       for (var j = 0; j < cTabsList.length; j++) {
        cDocsList = getDocs(cTabsList[j].document);
        // iterate over all documents
        for (var k = 0; k < cDocsList.length; k++) {
          cLinksList = cDocsList[k].links;
          // iterate over all links
          for (var l = 0; l < cLinksList.length; l++) {
            cHref = cLinksList[l].href;
            // apply filter
            if (regexp) {
              if (cHref.match(regexp)) {
                html += "<tr><td class=\"urllist\"><a href = \"" + cHref + "\">" + cHref + "</a></td></tr>";
              }
            } else {
              html += "<tr><td class=\"urllist\"><a href = \"" + cHref + "\">" + cHref + "</a></td></tr>";
            }
          }
        }
      }
    }
    html += "</table>";
  // display results
  openResultPage(html, _("List of links"));
  }
});